/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.<br/>
 * 项目名称 : 中科软支付平台
 * 创建日期 : 2016年12月14日
 * 修改历史 : 
 *     1. [2016年12月14日]创建文件 by liuyujia
 */
package com.sinosoft.sinopay.web.weixinpay.web.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSONObject;
import com.sinosoft.sinocloud.common.dto.ReportLogDTO;
import com.sinosoft.sinocloud.platform.base.SinoBaseController;
import com.sinosoft.sinopay.api.common.dto.pay.PaymentInfoDetailDTO;
import com.sinosoft.sinopay.payrules.config.ENUM_PAY_TYPE;
import com.sinosoft.sinopay.paytrade.config.ENUM_PAY_STATUS;
import com.sinosoft.sinopay.paytrade.dto.PaymentTradeReqDTO;
import com.sinosoft.sinopay.web.weixinpay.biz.config.ENUM_REPORT_NOTIFYTYPE;
import com.sinosoft.sinopay.web.weixinpay.biz.config.WechatView;
import com.sinosoft.sinopay.web.weixinpay.biz.service.PaymentWechatService;
import com.sinosoft.sinopay.web.weixinpay.biz.service.WechatSecurityService;
import com.sinosoft.sinopay.web.weixinpay.dto.WechatPaymentResultDTO;

/**  
 * 【微信支付请求入口Controller】
 * @author liuyujia
 * @date 2016年12月14日 下午7:00:06 
 * @version V1.0  
 */
@Controller
@RequestMapping("/sinopay/wechatPay")
public class WechatPayController extends SinoBaseController{

	@Autowired
	private WechatSecurityService wechatSecurityService;
	@Autowired
	private PaymentWechatService paymentWechatService;
	
	/**
	 * 微信授权
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "wechatPayRequest.do")
	public void wechatPay(HttpServletRequest request, HttpServletResponse response){
		ReportLogDTO tReportLogDTO = new ReportLogDTO();
		try{
			//1.接收请求参数
			String tPayNo = request.getParameter("payNo");
			String tSignMsg = request.getParameter("signMsg");
			
			//存日志信息 TODO
			
			//3.拼接授权参数
			String authorizeInfo="payNo="+tPayNo+"&signMsg="+tSignMsg;
			logger.info("授权参数:"+authorizeInfo);
			//获取授权地址
			String authorizeUrl = paymentWechatService.getAuthorizeInfo(authorizeInfo);
			//4.授权
			response.sendRedirect(authorizeUrl);
		}catch(Exception ex){
			logger.error("授权发生异常:/n" + ex.getMessage());
			ex.printStackTrace();
		}
	}
	
	/**
	 * 微信支付授权回调
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "authorizeCallback.do")
	public String wechatCallback(HttpServletRequest request, HttpServletResponse response, ModelMap model){
		response.setCharacterEncoding("utf-8");
		try{
			//1.获取授权信息
			String payNo = request.getParameter("payNo");
            String code = request.getParameter("code");
            String tSignMsg = request.getParameter("signMsg");
            String tPayWay = ENUM_PAY_TYPE.WXPAY.code();
            logger.info("授权信息：payNo="+payNo+"=======code="+code+"=======signMsg="+tSignMsg);
            
			//2.验签
			//2.1验证签名 
			wechatSecurityService.checkPayNoSignValid(payNo, tPayWay, tSignMsg);
			//2.2判断支付订单号支付状态 TODO
			wechatSecurityService.checkPayStatus(payNo);
			//4.根据授权信息的code获取openid TODO
			String accessInfo = paymentWechatService.getOpenidByCode(code);
			JSONObject json = JSONObject.parseObject(accessInfo);
        	String openid = json.getString("openid");
			logger.info("openid="+openid);
			//判断如果openid为null，重定向去授权
			if(openid==null){
				//3.拼接授权参数
				String authorizeInfo="payNo="+payNo+"&signMsg="+tSignMsg;
				logger.info("openid为null再次授权参数:"+authorizeInfo);
				//获取授权地址
				String authorizeUrl = paymentWechatService.getAuthorizeInfo(authorizeInfo);
				//4.授权
				response.sendRedirect(authorizeUrl);
			}
			//获取支付订单信息
			PaymentInfoDetailDTO tPaymentInfoDetailDTO = paymentWechatService.getPaymentTradeForPayNo(payNo);
			if(tPaymentInfoDetailDTO==null){
				logger.info("获取订单信息失败");
			}
			//5.验证客户请求合法性
			wechatSecurityService.checkCustomerByOpenid(openid, tPaymentInfoDetailDTO);
			//6.微信统一下单操作
			WechatPaymentResultDTO tWechatOrderResultDTO = paymentWechatService.wechatPrePayment(payNo, openid);
			//7.写支付主表信息
			paymentWechatService.addPaymentInfo(payNo);
			//8.统一下单结果信息转map
        	Map <String ,String > map = new HashMap<String ,String>();  
        	map.put("appId",tWechatOrderResultDTO.getAppId());
        	map.put("timeStamp", tWechatOrderResultDTO.getTimeStamp());
        	map.put("nonceStr", tWechatOrderResultDTO.getNonceStr());
        	map.put("pk", tWechatOrderResultDTO.getPackages());
        	map.put("paySign", tWechatOrderResultDTO.getPaySign());
        	map.put("signature",tWechatOrderResultDTO.getSignature());
        	map.put("payNo", payNo);
        	map.put("payAmount", String.valueOf(tWechatOrderResultDTO.getPayAmount()));
        	logger.info("payNo="+payNo+"payAmount="+tWechatOrderResultDTO.getPayAmount());
        	logger.info("package="+map.get("pk"));
        	model.addAttribute("map", map);
//        	request.setAttribute("map", map);
		}catch(Exception ex){
			logger.error("系统异常，信息为:/n" + ex);
            ex.printStackTrace();
		}
		//9.跳转页面
		String tReturnView = WechatView.PAY_MAIN_PAGE_VIEW;
		return tReturnView;
	}
	
	/**
	 * 查询商户回调地址
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value = "findMerchant.do")
	public void wechatNotifyMerchant(HttpServletRequest request, HttpServletResponse response, ModelMap model){
		logger.info("查询商户回调地址开始");
		response.setCharacterEncoding("utf-8");
		try{
			//1.获取支付号
			String tPayNo = request.getParameter("payNo");
			//2.获取支付订单信息
			PaymentInfoDetailDTO tPaymentInfoDetailDTO = paymentWechatService.getPaymentTradeForPayNo(tPayNo);
			//获取商户回调地址
			String tMerchantCode = tPaymentInfoDetailDTO.getMerchantCode();
			logger.info("支付订单号："+tPayNo+"对应的商户为:"+tMerchantCode);
			String tNotifyUrl = paymentWechatService.getNotifyUrlByMerchant(tMerchantCode, ENUM_REPORT_NOTIFYTYPE.PAGE_NOTIFY.code());
			logger.info("商户："+tMerchantCode+"的页面回调地址为："+tNotifyUrl);
			//7.统一下单结果信息转map
        	Map <String ,String > transMap = new HashMap<String ,String>();  
        	transMap.put("merchant", tMerchantCode);
        	transMap.put("notifyUrl", tNotifyUrl);
        	transMap.put("payNo", tPayNo);
        	this.renderJsonData(transMap, JsonType.JSON_OBJECT, request, response);
		}catch(Exception ex){
			logger.error("系统异常，信息为:/n" + ex);
            ex.printStackTrace();
		}
	}
	
	/**
	 * 记录回调信息
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value = "batchWechat.do")
	public void wechatBatchInfo(HttpServletRequest request, HttpServletResponse response, ModelMap model){
		logger.info("支付取消，记录回调信息");
		response.setCharacterEncoding("utf-8");
		try{
			//1.获取支付号
			String tPayNo = request.getParameter("payNo");
			logger.info("支付号为："+tPayNo);
			//2.获取支付订单信息
			PaymentInfoDetailDTO tPaymentInfoDetailDTO = paymentWechatService.getPaymentTradeForPayNo(tPayNo);
			//3.更新支付结果
			logger.info("更新支付主表开始");
			paymentWechatService.modifyTradeOrderStatus(tPayNo, ENUM_PAY_STATUS.PAY_CANCEL.code());
			PaymentTradeReqDTO tPaymentTradeReqDTO = new PaymentTradeReqDTO();
			tPaymentTradeReqDTO.setPayDate(new Date());//支付日期
			tPaymentTradeReqDTO.setPayNo(tPayNo);
			tPaymentTradeReqDTO.setModifyDate(new Date());
			tPaymentTradeReqDTO.setPayStatus(ENUM_PAY_STATUS.PAY_CANCEL.code()); 
			paymentWechatService.modifyPaymentInfo(tPaymentTradeReqDTO);
			//4.记录回调信息
			logger.info("记录回调信息");
			paymentWechatService.addPayTradeNotifyRecordByChanel(tPaymentInfoDetailDTO);
			logger.info("获取支付订单信息，支付号为："+tPaymentInfoDetailDTO.getPayNo());
			//查询回调地址
			String tMerchantCode = tPaymentInfoDetailDTO.getMerchantCode();
			logger.info("商户为:"+tMerchantCode);
			String tNotifyUrl = paymentWechatService.getNotifyUrlByMerchant(tMerchantCode, ENUM_REPORT_NOTIFYTYPE.PAGE_NOTIFY.code());
			logger.info("商户："+tMerchantCode+"的页面回调地址为："+tNotifyUrl);
			//7.统一下单结果信息转map
        	Map <String ,String > transMap = new HashMap<String ,String>();  
        	transMap.put("merchant", tMerchantCode);
        	transMap.put("notifyUrl", tNotifyUrl);
        	transMap.put("payNo", tPayNo);
        	this.renderJsonData(transMap, JsonType.JSON_OBJECT, request, response);
		}catch(Exception ex){
			logger.error("系统异常，信息为:/n" + ex);
            ex.printStackTrace();
		}
	}
}
